<template>
  <div class="problem-detail-page">
    <div class="container">
      <!-- 导航和操作按钮 -->
      <div class="navigation">
        <!-- 返回按钮 -->
        <button class="back-btn" @click="goBack" title="返回上一页">
          <i class="fas fa-arrow-left"></i>
          返回
        </button>
        
        <div class="action-buttons" v-if="problem && isMyQuestion">
          <button class="edit-btn" @click="editQuestion" title="编辑此题目的内容、描述、测试用例等信息">
            <i class="fas fa-edit"></i>
            编辑题目
          </button>
        </div>
      </div>

      <!-- 加载状态 -->
      <div v-if="loading" class="loading-container">
        <div class="loading-spinner">🔄</div>
        <p>正在加载题目详情...</p>
      </div>

      <!-- 错误状态 -->
      <div v-else-if="error" class="error-container">
        <div class="error-icon">❌</div>
        <h3>加载失败</h3>
        <p>{{ error }}</p>
        <button class="retry-btn" @click="loadProblemDetail">重试</button>
      </div>

      <!-- 题目详情内容 -->
      <div v-else-if="problem" class="problem-content">
        <!-- 题目头部信息 -->
        <div class="problem-header">
          <h1 class="problem-title">{{ problem.title }}</h1>
          <div class="problem-meta">
            <span class="problem-id">ID: {{ problem.id }}</span>
            <span :class="['type-tag', `type-${problem.type}`]">
              {{ problem.typeText }}
            </span>
            <span :class="['difficulty-tag', `level-${problem.difficulty}`]">
              难度: {{ problem.difficultyText }}
            </span>
            <span v-if="problem.completeRate" class="complete-rate">
              完成率: {{ problem.completeRate }}
            </span>
            <span v-if="problem.timeLimit" class="time-limit">
              时间限制: {{ problem.timeLimit }}ms
            </span>
            <span v-if="problem.spaceLimit" class="space-limit">
              空间限制: {{ formatSpaceLimit(problem.spaceLimit) }}
            </span>
            <span v-if="problem.label" class="problem-label">
              标签: {{ problem.label }}
            </span>
            <span :class="['public-tag', problem.isPublic ? 'public' : 'private']">
              {{ problem.isPublic ? '公开' : '私有' }}
            </span>
          </div>
        </div>

        <!-- 题目描述 -->
        <div class="problem-section">
          <h3>题目描述</h3>
          <div v-if="problem.description" class="problem-description" v-html="formatContent(problem.description)"></div>
          
          <!-- 🔥 题目描述图片 -->
          <div v-if="problem.questionDescribePicture" class="problem-describe-image">
            <img 
              :src="getImageUrl(problem.questionDescribePicture)" 
              :alt="problem.title + ' 题目描述图片'"
              class="describe-image"
              @error="onImageError"
              @load="onImageLoad"
            >
          </div>

        </div>

        <!-- 输入格式（编程题专用） -->
        <div v-if="isProgrammingQuestion && problem.inputFormat" class="problem-section">
          <h3>输入格式</h3>
          <div class="problem-input-format" v-html="formatContent(problem.inputFormat)"></div>
        </div>

        <!-- 输出格式（编程题专用） -->
        <div v-if="isProgrammingQuestion && problem.outputFormat" class="problem-section">
          <h3>输出格式</h3>
          <!-- 🔥 根据 outputFormat 内容判断是文本还是图片路径 -->
          
          <!-- 如果 outputFormat 是图片URL（包含图片扩展名），显示图片 -->
          <div v-if="isImageUrl(problem.outputFormat)" class="output-image-container">
            <img 
              :src="getImageUrl(problem.outputFormat)" 
              :alt="problem.title + ' 输出格式图片'"
              class="output-format-image"
              @error="onImageError"
              @load="onImageLoad"
            >
            <p class="image-caption">输出格式示例图</p>
          </div>
          
          <!-- 否则显示为文本 -->
          <div v-else class="problem-output-format" v-html="formatContent(problem.outputFormat)"></div>
        </div>

        <!-- 数据范围和提示 -->
        <div v-if="problem.rangeAndPrompt" class="problem-section">
          <h3>数据范围和提示</h3>
          <div class="problem-range-prompt" v-html="formatContent(problem.rangeAndPrompt)"></div>
        </div>

        <!-- 测试用例（简洁显示） -->
        <div v-if="problem.testCasesText" class="problem-section">
          <h3>测试用例</h3>
          <div class="test-cases-container">
            <div v-for="(testCase, index) in parseTestCases(problem.testCasesText)" 
                 :key="index" 
                 class="test-case-item">
              <div class="test-case-header-mini">
                <span class="case-number">测试用例 {{ index + 1 }}</span>
              </div>
              <div class="test-case-data">
                <div class="test-case-section">
                  <label>输入格式</label>
                  <div class="input-data">{{ testCase.input || '无输入' }}</div>
                </div>
                <div class="test-case-section">
                  <label>输出格式</label>
                  <!-- 如果output是图片URL，显示图片 -->
                  <div v-if="isImageUrl(testCase.output)" class="output-image-data">
                    <img :src="getImageUrl(testCase.output)" alt="输出格式图片" class="test-case-image" @error="onImageError">
                  </div>
                  <!-- 否则显示文本 -->
                  <div v-else class="output-data">{{ testCase.output || '无输出' }}</div>
                </div>
              </div>
            </div>
          </div>
        </div>

        <!-- 测试数据 -->
        <div v-if="problem.testDataText" class="problem-section">
          <h3>测试数据</h3>
          <div class="test-cases-container">
            <div v-for="(testData, index) in parseTestData(problem.testDataText)" 
                 :key="index" 
                 class="test-case-item">
              <div class="test-case-header-mini">
                <span class="case-number">测试数据 {{ index + 1 }}</span>
              </div>
              <div class="test-case-data">
                <div class="test-case-section">
                  <div class="input-data">{{ testData.content || '无数据' }}</div>
                </div>
              </div>
            </div>
          </div>
        </div>

        <!-- 参考程序结果图片 -->
        <div v-if="problem.questionPicture" class="problem-section">
          <h3>参考程序结果</h3>
          <div class="problem-image-container">
            <img 
              :src="getImageUrl(problem.questionPicture)" 
              :alt="problem.title + ' 参考程序结果'"
              class="problem-image-small"
              @error="onImageError"
              @load="onImageLoad"
            >
            <p class="image-caption">参考程序结果图</p>
          </div>
        </div>

        <!-- 题目选项（选择题专用） -->
        <div v-if="isChoiceQuestion && problem.options" class="problem-section">
          <h3>选项</h3>
          <div class="problem-options">
            <div 
              v-for="(option, index) in problem.options" 
              :key="index"
              class="option-item"
            >
              <span class="option-label">{{ getOptionLabel(index) }}.</span>
              <span class="option-text">{{ option.text || option }}</span>
            </div>
          </div>
        </div>

        <!-- 正确答案（非程序题显示） -->
        <div v-if="problem.answer && showAnswer && !isProgrammingQuestion" class="problem-section answer-section">
          <h3>正确答案</h3>
          <div class="answer-container">
            <div class="problem-answer" style="white-space: pre !important;">{{ problem.answer }}</div>
            <div class="answer-actions">
              <button 
                class="copy-answer-btn" 
                @click="copyCorrectAnswer"
                title="复制正确答案"
              >
                <i class="fas fa-copy"></i> 复制答案
              </button>
            </div>
          </div>
        </div>

        <!-- 答案代码（编程题专用，显示答案时显示） -->
        <div v-if="showAnswer && isProgrammingQuestion" class="problem-section answer-code-section">
          <h3>
            参考答案代码
            <span v-if="loadingAnswer" class="loading-indicator">
              <i class="fas fa-spinner fa-spin"></i> 加载中...
            </span>
          </h3>
          <div v-if="!loadingAnswer" class="answer-code-container">
            <pre class="answer-code" style="white-space: pre !important;"><code style="white-space: inherit !important;">{{ answerCode || '// 暂无参考答案代码' }}</code></pre>
            <div class="code-actions">
              <button 
                class="copy-code-btn" 
                @click="copyAnswerCode"
                :disabled="!answerCode"
                title="复制答案代码"
              >
                <i class="fas fa-copy"></i> 复制代码
              </button>
            </div>
          </div>
        </div>

        <!-- 数据来源说明 -->
        <div v-if="problem.source === 'local'" class="data-source-notice">
          <i class="fas fa-info-circle"></i>
          此题目保存在本地浏览器中，您可以随时编辑修改
        </div>

        <!-- 题目解析 -->
        <div v-if="problem.explanation" class="problem-section">
          <h3>题目解析</h3>
          <div class="problem-explanation" v-html="formatContent(problem.explanation)"></div>
        </div>

        <!-- 代码模板（编程题专用） -->
        <div v-if="isProgrammingQuestion && problem.codeTemplate" class="problem-section">
          <h3>代码模板</h3>
          <pre class="code-template"><code>{{ problem.codeTemplate }}</code></pre>
        </div>



        <!-- 题目标签 -->
        <div v-if="problem.tags && problem.tags.length > 0" class="problem-section">
          <h3>标签</h3>
          <div class="problem-tags">
            <span 
              v-for="tag in problem.tags" 
              :key="tag"
              class="tag-item"
            >
              {{ tag }}
            </span>
          </div>
        </div>

        <!-- 题目信息 -->
        <div v-if="problem.createTime || problem.updateTime" class="problem-section info-section">
          <h3>题目信息</h3>
          <div class="problem-info">
            <div v-if="problem.createTime" class="info-item">
              <strong>创建时间：</strong>{{ formatDateTime(problem.createTime) }}
            </div>
            <div v-if="problem.updateTime" class="info-item">
              <strong>更新时间：</strong>{{ formatDateTime(problem.updateTime) }}
            </div>
            <div v-if="problem.courseId" class="info-item">
              <strong>课程ID：</strong>{{ problem.courseId }}
            </div>
          </div>
        </div>

        <!-- 操作按钮 -->
        <div class="problem-actions">
          <button 
            v-if="!showAnswer" 
            class="action-btn show-answer-btn" 
            :class="{ 'disabled': isStudent }"
            :disabled="isStudent"
            @click="toggleAnswer"
            :title="isStudent ? '学生账号不能查看答案' : '点击查看答案代码'"
          >
            显示答案
            <span v-if="isStudent" class="student-lock">🔒</span>
          </button>
          <button v-else class="action-btn hide-answer-btn" @click="toggleAnswer">
            隐藏答案
          </button>
          <button class="action-btn start-solve-btn" @click="startSolving">
            开始解题
          </button>
        </div>

        <!-- Goc判题组件 -->
        <div v-if="showGocJudge" class="goc-judge-section">
          <div class="section-header">
            <h3>在线编程练习</h3>
            <button class="close-judge-btn" @click="hideGocJudge">关闭</button>
          </div>
          <GocJudge
            :problemId="problemId"
            :answerCode="answerCode"
            :fullProblemInfo="problem"
            :judgeMode="'loose'"
            :tolerance="2"
            :showDebugInfo="false"
            @judge-complete="onJudgeComplete"
            @code-submit="onCodeSubmit"
            @error="onJudgeError"
          />
        </div>
      </div>

      <!-- 无数据状态 -->
      <div v-else class="no-data-container">
        <div class="no-data-icon">📭</div>
        <h3>题目不存在</h3>
        <p>未找到指定的题目信息</p>
      </div>
    </div>
  </div>
</template>

<script>
import { getTestQuestionById, getTestCode } from '@/api/testQuestion'
import GocJudge from '@/components/GocJudge.vue'
import logger from '../utils/logger.js'

export default {
  name: 'ProblemDetail',
  components: {
    GocJudge
  },
  data() {
    return {
      problem: null,
      loading: true,
      error: null,
      showAnswer: false,
      showGocJudge: false,
      answerCode: '', // 存储题目答案代码
      loadingAnswer: false, // 答案加载状态
      answerTrace: null // 存储答案代码的trace数据
    }
  },
  
  computed: {
    problemId() {
      return this.$route.params.id
    },
    
    // 是否为选择题（单选、多选、判断）
    isChoiceQuestion() {
      return this.problem && ['1', '2', '3'].includes(this.problem.type)
    },
    
    // 是否为编程题
    isProgrammingQuestion() {
      // 程序题类型为 '4'
      return this.problem && this.problem.type === '4'
    },

    // 是否为当前用户的题目
    isMyQuestion() {
      if (!this.problem) return false;
      
      try {
        // 获取当前用户ID
        const currentUserId = this.getCurrentUserId();
        return String(this.problem.createUserId) === String(currentUserId);
      } catch (error) {
        logger.error('❌ [ProblemDetail] 检查题目所有权失败:', error);
        return false;
      }
    },
    
    // 是否为学生账号
    isStudent() {
      try {
        // 首先从JWT令牌中获取role
        const token = localStorage.getItem('token')
        if (token) {
          try {
            const tokenParts = token.split('.')
            if (tokenParts.length === 3) {
              const payloadStr = atob(tokenParts[1])
              
              // 使用正则表达式提取role
              const roleMatch = payloadStr.match(/"role":(\d+)/)
              if (roleMatch && roleMatch[1]) {
                return parseInt(roleMatch[1]) === 3
              }
              
              // 备用方案：使用JSON.parse
              const payload = JSON.parse(payloadStr)
              const role = payload.claims?.role
              if (role !== undefined) {
                return parseInt(role) === 3
              }
            }
          } catch (tokenError) {
            // JWT解析失败，继续尝试其他方法
          }
        }
        
        // 备选方案：从localStorage获取用户信息
        const userInfoStr = localStorage.getItem('userInfo')
        if (userInfoStr) {
          const userInfo = JSON.parse(userInfoStr)
          const role = userInfo.role
          if (role !== undefined) {
            const roleNum = typeof role === 'string' ? parseInt(role) : role
            return roleNum === 3
          }
        }
      } catch (error) {
        // 获取失败，默认不是学生
      }
      
      return false // 默认不是学生
    }
  },
  
  async mounted() {
    await this.loadProblemDetail()
  },
  
  methods: {
    // 返回上一页
    goBack() {
      // 使用 Vue Router 的返回功能，会保持页码和筛选状态
      this.$router.go(-1)
    },
    
    // 加载题目详情
    async loadProblemDetail() {
      if (!this.problemId) {
        this.error = '缺少题目ID参数'
        this.loading = false
        return
      }
      
      this.loading = true
      this.error = null
      
      try {
        logger.log('🔍 开始加载题目详情，ID:', this.problemId)
        
        // 优先从API加载最新数据
        try {
          logger.log('🌐 [ProblemDetail] 优先从API加载最新题目数据...')
          const response = await getTestQuestionById(this.problemId)
          
          logger.log('📦 [ProblemDetail] API返回的响应:', response)
          
          // axios拦截器已经返回了response.data，所以直接检查response.code
          if (response && response.code === 0 && response.data) {
            this.problem = this.formatProblemData(response.data)
            logger.log('✅ 题目详情从API加载成功:', this.problem)
            
            // API加载成功后，同步更新本地存储
            try {
              const { default: localQuestionStorage } = await import('@/utils/localStorage');
              localQuestionStorage.updateQuestion(this.problemId, response.data);
              logger.log('💾 [ProblemDetail] 已同步更新本地存储');
            } catch (syncError) {
              logger.warn('⚠️ [ProblemDetail] 同步本地存储失败:', syncError);
            }
            
            return; // API 加载成功，直接返回
          } else {
            logger.warn('⚠️ [ProblemDetail] API响应格式异常，尝试使用本地存储');
            throw new Error('API响应格式异常');
          }
        } catch (apiError) {
          logger.warn('⚠️ [ProblemDetail] API加载失败，尝试从本地存储加载:', apiError);
          
          // API失败时，使用本地存储作为备选方案
          try {
            const { default: localQuestionStorage } = await import('@/utils/localStorage');
            const localQuestion = localQuestionStorage.getQuestionById(this.problemId);
            
            if (localQuestion) {
              logger.log('✅ [ProblemDetail] 从本地存储找到题目（备选方案）:', localQuestion);
              this.problem = this.formatProblemData(localQuestion);
              logger.log('✅ 题目详情从本地存储加载成功（备选）:', this.problem);
              return;
            } else {
              logger.error('❌ [ProblemDetail] 本地存储中也未找到题目');
              throw new Error('无法从API或本地存储加载题目数据');
            }
          } catch (localError) {
            logger.error('❌ [ProblemDetail] 本地存储加载也失败:', localError);
            throw apiError; // 抛出原始API错误
          }
        }
      } catch (error) {
        logger.error('❌ 题目详情加载失败:', error)
        
        if (error.response?.status === 404) {
          this.error = '题目不存在'
        } else if (error.response?.status === 401) {
          this.error = '权限不足，请先登录'
        } else if (error.response?.status === 403) {
          this.error = '权限不足，无法查看此题目'
        } else {
          this.error = error.message || '加载失败，请稍后重试'
        }
      } finally {
        this.loading = false
      }
    },
    
    // 格式化题目数据
    formatProblemData(rawData) {
      logger.log('🔄 [详情页] 开始格式化题目数据:', rawData)
      logger.log('🔍 [详情页] 原始数据中的strict:', rawData.strict)
      logger.log('🔍 [详情页] strict类型:', typeof rawData.strict)
      
      const formatted = {
        id: rawData.id || rawData.testQuestionId,
        title: rawData.questionName || rawData.title || rawData.questionTitle || '未知题目',
        description: rawData.questionDescribe || rawData.questionDescription || rawData.description || rawData.content || '暂无题目描述',
        type: String(rawData.questionType || rawData.type || ''),
        typeText: this.getTypeText(rawData.questionType || rawData.type),
        difficulty: rawData.difficulty || rawData.difficultyLevel || '',
        difficultyText: String(rawData.difficulty || rawData.difficultyLevel || '未知'),
        completeRate: rawData.completeRate || rawData.completionRate,
        answer: rawData.testCode || rawData.answer || rawData.correctAnswer, // 使用testCode作为答案
        explanation: rawData.explanation || rawData.analysis,
        options: rawData.options || rawData.choices,
        codeTemplate: rawData.codeTemplate || rawData.templateCode,
        testCases: this.parseTestCases(rawData.testCases) || rawData.testCaseList || rawData.examples || [],
        testCasesText: rawData.testCases, // 原始测试用例文本
        testDataText: rawData.testData, // 原始测试数据文本
        tags: rawData.tags || rawData.labels || [],
        // 新增字段映射
        inputFormat: rawData.inputFormat,
        outputFormat: rawData.outputFormat, // 输出格式：可以是文本描述或图片路径
        rangeAndPrompt: rawData.rangeAndPrompt, // 使用正确的字段名
        spaceLimit: rawData.spaceLimitation || rawData.spaceLimit, // 使用正确的字段名
        timeLimit: rawData.timeLimit,
        courseId: rawData.courseLevelId || rawData.courseId, // 使用正确的字段名
        label: rawData.label,
        isPublic: rawData.isPublic,
        isDeleted: rawData.isDeleted,
        createTime: rawData.createTime,
        updateTime: rawData.updateTime,
        createUserId: rawData.createUserId, // 添加创建者ID字段
        questionPicture: rawData.questionPicture, // 添加题目图片URL字段
        questionDescribePicture: rawData.questionDescribePicture, // 🔥 添加题目描述图片路径字段
        strict: rawData.strict !== undefined ? rawData.strict : '0' // 🔥 添加严格判题字段（string类型）
      }
      
      logger.log('✅ [详情页] 格式化完成:', formatted)
      logger.log('🔍 [详情页] 格式化后的strict:', formatted.strict)
      return formatted
    },
    
    // 获取题目类型文本
    getTypeText(type) {
      const typeMap = {
        '1': '选择题',
        '2': '判断题', 
        '3': '填空题',
        '4': '程序题'
      }
      return typeMap[type] || '未知类型'
    },
    
    // 获取选项标签（A, B, C, D...）
    getOptionLabel(index) {
      return String.fromCharCode(65 + index) // A, B, C, D...
    },
    
    // 格式化内容（处理换行和HTML转义）
    formatContent(content) {
      if (!content) return ''
      
      // 先转义HTML特殊字符，防止被当作HTML标签解析
      const escaped = content
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#039;')
      
      // 然后将换行符转换为<br>
      return escaped.replace(/\n/g, '<br>')
    },
    
    // 格式化测试用例JSON字符串（保留原方法兼容性）
    formatTestCases(testCasesStr) {
      if (!testCasesStr) return ''
      
      try {
        // 尝试解析JSON并格式化
        const parsed = JSON.parse(testCasesStr)
        return JSON.stringify(parsed, null, 2)  // 缩进2个空格
      } catch (error) {
        logger.warn('⚠️ [ProblemDetail] 测试用例不是有效的JSON，直接显示:', error)
        // 如果不是JSON格式，直接返回原始字符串
        return testCasesStr
      }
    },

    // 解析测试用例JSON为数组对象
    parseTestCases(testCasesStr) {
      if (!testCasesStr) return []
      
      try {
        // 尝试解析JSON
        const parsed = JSON.parse(testCasesStr)
        logger.log('✅ [ProblemDetail] 测试用例解析成功:', parsed)
        
        // 确保返回数组格式
        if (Array.isArray(parsed)) {
          return parsed
        } else {
          // 如果不是数组，包装成数组
          return [parsed]
        }
      } catch (error) {
        logger.warn('⚠️ [ProblemDetail] 测试用例JSON解析失败:', error)
        // 解析失败时返回空数组
        return []
      }
    },

    // 解析测试数据JSON为数组对象
    parseTestData(testDataStr) {
      if (!testDataStr) return []
      
      try {
        // 尝试解析JSON
        const parsed = JSON.parse(testDataStr)
        logger.log('✅ [ProblemDetail] 测试数据解析成功:', parsed)
        
        // 确保返回数组格式
        if (Array.isArray(parsed)) {
          return parsed
        } else {
          // 如果不是数组，包装成数组
          return [parsed]
        }
      } catch (error) {
        logger.warn('⚠️ [ProblemDetail] 测试数据JSON解析失败:', error)
        // 解析失败时返回空数组
        return []
      }
    },

    // 判断是否是图片URL
    isImageUrl(text) {
      if (!text) return false
      
      // 包含图片文件扩展名
      const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp']
      const lowerText = text.toLowerCase()
      
      // 检查是否包含图片扩展名
      const hasImageExtension = imageExtensions.some(ext => lowerText.includes(ext))
      
      // 检查是否是URL格式（http开头或包含特殊格式）
      const isUrl = text.startsWith('http') || 
                    text.startsWith('/api/') || 
                    text.includes('文件上传成功')
      
      const result = hasImageExtension && isUrl
      
      if (result) {
        logger.log('🖼️ [ProblemDetail] 检测到图片URL:', text)
      }
      
      return result
    },
    
    // 获取图片URL（拼接服务器地址）
    getImageUrl(imagePath) {
      logger.log('🖼️ [ProblemDetail] 处理图片路径:', imagePath)
      if (!imagePath) return ''
      
      // 🔥 处理后端返回的特殊格式："文件上传成功，文件的url为：[URL]"
      if (imagePath.includes('文件上传成功') && imagePath.includes('url为：')) {
        const urlMatch = imagePath.match(/url为：(.+)$/);
        if (urlMatch && urlMatch[1]) {
          const extractedUrl = urlMatch[1].trim();
          logger.log('✅ [ProblemDetail] 从特殊格式中提取URL:', extractedUrl);
          return extractedUrl;
        }
      }
      
      // 如果已经是完整URL，直接返回
      if (imagePath.startsWith('http')) {
        logger.log('🌐 [ProblemDetail] 图片已是完整URL:', imagePath)
        return imagePath
      }
      
      // 从全局配置获取baseURL
      const GLOBAL_CONFIG = window.GLOBAL_CONFIG || {}
      const baseURL = GLOBAL_CONFIG.API_BASE_URL || 'http://localhost:8000'
      
      // 如果路径已经包含/api/，直接拼接baseURL
      const fullUrl = baseURL + imagePath
      logger.log('🔗 [ProblemDetail] baseURL:', baseURL)
      logger.log('🔗 [ProblemDetail] imagePath:', imagePath)
      logger.log('🔗 [ProblemDetail] 拼接后的图片URL:', fullUrl)
      return fullUrl
    },
    
    // 切换答案显示状态
    async toggleAnswer() {
      // 检查用户身份，学生（role=3）不能查看答案
      if (!this.showAnswer) {
        const userRole = this.getUserRole()
        logger.log('🔍 [ProblemDetail] 当前用户角色:', userRole)
        
        if (userRole === 3) {
          logger.warn('⚠️ [ProblemDetail] 学生账号不能查看答案')
          alert('⚠️ 学生账号不能查看答案，请自己完成题目！')
          return
        }
        
        // 显示答案时调用API获取答案代码
        await this.loadAnswerCode()
      }
      this.showAnswer = !this.showAnswer
    },
    
    // 获取当前用户的角色
    getUserRole() {
      try {
        // 首先从JWT令牌中获取role
        const token = localStorage.getItem('token')
        if (token) {
          try {
            const tokenParts = token.split('.')
            if (tokenParts.length === 3) {
              const payloadStr = atob(tokenParts[1])
              logger.log('🔍 [ProblemDetail] JWT payload字符串:', payloadStr)
              
              // 使用正则表达式提取role
              const roleMatch = payloadStr.match(/"role":(\d+)/)
              if (roleMatch && roleMatch[1]) {
                const role = parseInt(roleMatch[1])
                logger.log('👤 [ProblemDetail] 从JWT令牌获取用户角色:', role)
                return role
              }
              
              // 备用方案：使用JSON.parse
              const payload = JSON.parse(payloadStr)
              const role = payload.claims?.role
              if (role !== undefined) {
                logger.log('👤 [ProblemDetail] 从JWT claims获取用户角色:', role)
                return parseInt(role)
              }
            }
          } catch (tokenError) {
            logger.warn('⚠️ [ProblemDetail] JWT令牌解析失败:', tokenError)
          }
        }
        
        // 备选方案：从localStorage获取用户信息
        const userInfoStr = localStorage.getItem('userInfo')
        if (userInfoStr) {
          const userInfo = JSON.parse(userInfoStr)
          logger.log('👤 [ProblemDetail] 从localStorage获取用户信息:', userInfo)
          const role = userInfo.role
          if (role !== undefined) {
            // role可能是数字或字符串
            const roleNum = typeof role === 'string' ? parseInt(role) : role
            logger.log('👤 [ProblemDetail] 从localStorage获取用户角色:', roleNum)
            return roleNum
          }
        }
      } catch (error) {
        logger.error('❌ [ProblemDetail] 获取用户角色失败:', error)
      }
      
      logger.warn('⚠️ [ProblemDetail] 无法获取用户角色，默认返回0')
      return 0 // 默认返回0，表示未知角色
    },

    // 加载题目答案代码
    async loadAnswerCode() {
      if (!this.problemId) {
        logger.error('❌ 题目ID不存在，无法获取答案代码')
        return
      }

      // 如果已经有答案代码，直接返回
      if (this.answerCode) {
        logger.log('✅ 答案代码已存在，无需重复加载')
        return
      }

      // 如果题目详情中已经包含答案，直接使用
      if (this.problem && this.problem.answer) {
        logger.log('✅ 从题目详情中获取答案代码:', this.problem.answer)
        // 确保换行符被正确处理（处理可能的转义字符）
        this.answerCode = this.problem.answer.replace(/\\n/g, '\n').replace(/\\t/g, '\t')
        logger.log('🔍 处理后的答案代码:', this.answerCode)
        logger.log('🔍 答案代码包含的换行符数量:', (this.answerCode.match(/\n/g) || []).length)
        return
      }

      this.loadingAnswer = true
      
      try {
        logger.log('🔍 开始获取题目答案代码，题目ID:', this.problemId)
        
        const response = await getTestCode(this.problemId)
        logger.log('📦 答案代码API响应:', response)
        
        if (response && response.data) {
          // 根据接口返回的数据结构提取答案代码
          if (response.data.code === 0 && response.data.data) {
            // 确保换行符被正确处理（处理可能的转义字符）
            this.answerCode = response.data.data.replace(/\\n/g, '\n').replace(/\\t/g, '\t')
            logger.log('✅ 答案代码获取成功:', this.answerCode)
            logger.log('🔍 答案代码包含的换行符数量:', (this.answerCode.match(/\n/g) || []).length)
          } else if (typeof response.data === 'string') {
            // 如果直接返回代码字符串
            this.answerCode = response.data.replace(/\\n/g, '\n').replace(/\\t/g, '\t')
            logger.log('✅ 答案代码获取成功（字符串格式）')
            logger.log('🔍 答案代码包含的换行符数量:', (this.answerCode.match(/\n/g) || []).length)
          } else {
            logger.warn('⚠️ 答案代码响应格式异常:', response.data)
            this.answerCode = '// 答案代码格式异常，请联系管理员'
          }
        } else {
          logger.warn('⚠️ 答案代码响应为空')
          this.answerCode = '// 暂无答案代码'
        }

        // 🔥 新增功能：将答案代码转换为trace
        if (this.answerCode && this.answerCode.trim() && !this.answerCode.startsWith('//')) {
          try {
            logger.log('🎯 开始将答案代码转换为trace...')
            
            // 动态导入所需的工具函数
            const { tokenize } = await import('@/utils/goc-tokenizer')
            const { parse } = await import('@/utils/goc-parser')
            const { execute } = await import('@/utils/goc-interpreter')
            const { default: TraceCollector } = await import('@/utils/goc-trace-collector')
            
            // 创建trace收集器
            const traceCollector = new TraceCollector()
            
            // 创建虚拟canvas上下文（用于执行代码但不实际绘制）
            const virtualCanvas = document.createElement('canvas')
            virtualCanvas.width = 800
            virtualCanvas.height = 600
            const virtualCtx = virtualCanvas.getContext('2d')
            
            // 预处理答案代码：提取GOC绘图命令
            let processedCode = this.answerCode.trim()
            
            // 🔥 改进的GOC绘图命令提取逻辑
            const gocDrawingCommands = []
            
            // 🎯 首先提取所有可能的GOC指令（包括条件语句内的）
            logger.log('🔍 开始全面扫描GOC指令...')
            
            // 🔥 扩展的GOC方法列表（包含所有指定的指令）
            const gocMethods = [
              // 基本运动控制
              'fd', 'bk', 'rt', 'lt', 'moveTo', 'lineTo',
              // 笔状态控制
              'up', 'down', 'size', 'speed', 'show', 'hide',
              // 颜色控制
              'c', 'rgb',
              // 几何图形绘制
              'o', 'oo',           // 圆形（空心、实心）
              'e', 'ee',           // 椭圆（空心、实心）
              'r', 'rr',           // 矩形（空心、实心）
              // 图片操作
              'pic',
              // 文本操作
              'text', 'setprecision', 'textSize', 'textU', 'font',
              // 系统控制
              'cls',               // 清屏
              'wait',              // 等待
              // 辅助功能
              'showXY'
            ]
            
            // 🎯 控制流、IO和声明指令列表（需要特殊处理）
            const controlFlowPatterns = [
              // 循环结构
              /for\s*\([^)]*\)\s*\{[^}]*\}/g,
              // 条件结构
              /if\s*\([^)]*\)\s*\{[^}]*\}/g,
              // 输入指令
              /cin\s*>>\s*[^;]+/g,
              /cinWin\s*\([^)]*\)/g,
              // 输出指令
              /cout\s*<<[^;]+/g,
              /cout\s*<<\s*endl/g,
              /cout\s*<<\s*setprecision\([^)]*\)/g,
              // 🔥 新增：数组声明
              /(?:int|float|double|char|bool)\s+[a-zA-Z_][a-zA-Z0-9_]*\s*\[\s*\d+\s*\]\s*;/g,
              // 🔥 新增：变量声明
              /(?:int|float|double|char|bool)\s+[a-zA-Z_][a-zA-Z0-9_]*(?:\s*,\s*[a-zA-Z_][a-zA-Z0-9_]*)*(?:\s*=\s*[^;]+)?\s*;/g
            ]
            
            // 构建匹配链式调用的正则表达式
            // 匹配 p.xxx(...).yyy(...).zzz(...) 或 pen.xxx(...).yyy(...).zzz(...) 的完整链式调用
            const methodPattern = `(?:${gocMethods.join('|')})`
            const chainPattern = new RegExp(
              `(?:p|pen)\\.${methodPattern}\\([^)]*\\)(?:\\.${methodPattern}\\([^)]*\\))*`,
              'g'
            )
            
            const chainCommands = processedCode.match(chainPattern)
            logger.log('🔍 链式调用匹配结果:', chainCommands)
            
            // 🔥 额外检查：确保完整链式调用被正确识别
            if (chainCommands) {
              chainCommands.forEach((chain, index) => {
                logger.log(`📋 第${index + 1}个链式调用完整内容:`, chain)
                
                // 计算这个链式调用应该包含多少个方法
                const expectedMethodCount = (chain.match(/\./g) || []).length
                logger.log(`🔢 预期方法数量: ${expectedMethodCount}`)
              })
            }
            
            if (chainCommands) {
              chainCommands.forEach((chainCmd, index) => {
                logger.log(`🔗 处理第${index + 1}个链式调用:`, chainCmd)
                
                // 统一转换为pen.xxx()格式
                const normalizedChain = chainCmd.replace(/^p\./, 'pen.')
                logger.log('📝 标准化链式调用:', normalizedChain)
                
                // 🎯 拆分链式调用为单独的方法调用（只保留拆分后的单独调用）
                const individualCalls = []
                let currentChain = normalizedChain
                
                // 提取每个单独的方法调用
                const singleCallPattern = new RegExp(`\\.?(${methodPattern})\\(([^)]*)\\)`, 'g')
                let match
                while ((match = singleCallPattern.exec(currentChain)) !== null) {
                  const methodName = match[1]
                  const methodArgs = match[2]
                  const individualCall = `pen.${methodName}(${methodArgs})`
                  individualCalls.push(individualCall)
                  logger.log(`  ↳ 拆分出单个调用: ${individualCall}`)
                }
                
                logger.log(`🎯 从链式调用中拆分出 ${individualCalls.length} 个单独调用:`, individualCalls)
                
                // 🔥 添加所有拆分后的单独调用（允许相同指令多次调用）
                individualCalls.forEach(call => {
                  gocDrawingCommands.push(call)
                  logger.log(`  ➕ 添加指令: ${call}`)
                })
              })
            }
            
            // 🔥 新增：提取控制流和IO指令
            logger.log('🎯 开始提取控制流和IO指令...')
            
            // 🔥 改进：按优先级顺序处理不同类型的指令
            const processedMatches = new Set() // 记录已处理的匹配项，避免重复
            
            controlFlowPatterns.forEach((pattern, index) => {
              const matches = processedCode.match(pattern)
              if (matches) {
                matches.forEach(match => {
                  const trimmedMatch = match.trim()
                  
                  // 跳过已处理的匹配项
                  if (processedMatches.has(trimmedMatch)) {
                    return
                  }
                  processedMatches.add(trimmedMatch)
                  
                  logger.log(`🔄 发现控制流/IO/声明指令:`, trimmedMatch)
                  
                  // 🎯 根据指令类型进行分类处理，转换为可执行的trace指令
                  if (trimmedMatch.includes('for')) {
                    // 提取for循环的条件
                    const forMatch = trimmedMatch.match(/for\s*\(([^)]*)\)/)
                    const condition = forMatch ? forMatch[1] : 'unknown'
                    gocDrawingCommands.push(`pen.recordControlFlow('for', '${condition}')`)
                    logger.log(`  ➕ 添加FOR循环trace指令`)
                  } else if (trimmedMatch.includes('if')) {
                    // 提取if条件
                    const ifMatch = trimmedMatch.match(/if\s*\(([^)]*)\)/)
                    const condition = ifMatch ? ifMatch[1] : 'unknown'
                    gocDrawingCommands.push(`pen.recordControlFlow('if', '${condition}')`)
                    logger.log(`  ➕ 添加IF条件trace指令`)
                  } else if (trimmedMatch.includes('cin')) {
                    // 🎯 处理输入指令 - args显示存储数据的变量或数组
                    if (trimmedMatch.includes('cinWin')) {
                      const cinWinMatch = trimmedMatch.match(/cinWin\s*\(([^)]*)\)/)
                      const params = cinWinMatch ? cinWinMatch[1] : ''
                      gocDrawingCommands.push(`pen.recordIO('cinWin', '${params}')`)
                    } else {
                      // 提取变量名，支持数组访问如 a[i]
                      const inputVar = trimmedMatch.replace(/cin\s*>>\s*/, '').replace(/;.*/, '').trim()
                      gocDrawingCommands.push(`pen.recordIO('cin', '${inputVar}')`)
                      logger.log(`  ➕ 添加输入trace指令: cin >> ${inputVar}`)
                    }
                  } else if (trimmedMatch.includes('cout')) {
                    // 处理输出指令
                    if (trimmedMatch.includes('endl')) {
                      gocDrawingCommands.push(`pen.recordIO('cout', 'endl')`)
                    } else if (trimmedMatch.includes('setprecision')) {
                      const precMatch = trimmedMatch.match(/setprecision\(([^)]*)\)/)
                      const precision = precMatch ? precMatch[1] : '6'
                      gocDrawingCommands.push(`pen.recordIO('cout_setprecision', '${precision}')`)
                    } else {
                      const output = trimmedMatch.replace(/cout\s*<<\s*/, '').replace(/;.*/, '')
                      gocDrawingCommands.push(`pen.recordIO('cout', '${output}')`)
                    }
                    logger.log(`  ➕ 添加输出trace指令`)
                  } else if (trimmedMatch.match(/(?:int|float|double|char|bool)\s+[a-zA-Z_][a-zA-Z0-9_]*\s*\[\s*\d+\s*\]\s*;/)) {
                    // 🔥 处理数组声明
                    const arrayMatch = trimmedMatch.match(/(int|float|double|char|bool)\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*\[\s*(\d+)\s*\]\s*;/)
                    if (arrayMatch) {
                      const dataType = arrayMatch[1]
                      const arrayName = arrayMatch[2]
                      const arraySize = arrayMatch[3]
                      gocDrawingCommands.push(`pen.recordDeclaration('array', '${dataType} ${arrayName}[${arraySize}]', '${dataType}', '${arrayName}', ${arraySize})`)
                      logger.log(`  ➕ 添加数组声明trace指令: ${dataType} ${arrayName}[${arraySize}]`)
                    }
                  } else if (trimmedMatch.match(/(?:int|float|double|char|bool)\s+[a-zA-Z_][a-zA-Z0-9_]*(?:\s*,\s*[a-zA-Z_][a-zA-Z0-9_]*)*(?:\s*=\s*[^;]+)?\s*;/)) {
                    // 🔥 处理变量声明
                    const varMatch = trimmedMatch.match(/(int|float|double|char|bool)\s+(.+);/)
                    if (varMatch) {
                      const dataType = varMatch[1]
                      const declaration = varMatch[2].trim()
                      gocDrawingCommands.push(`pen.recordDeclaration('variable', '${dataType} ${declaration}', '${dataType}', '${declaration}')`)
                      logger.log(`  ➕ 添加变量声明trace指令: ${dataType} ${declaration}`)
                    }
                  }
                })
              }
            })
            
            // 🎯 处理单独的非链式调用（不在链式调用中的独立调用）
            gocMethods.forEach(method => {
              // 匹配单独的方法调用，但排除已经在链式调用中处理过的
              const singleMethodRegex = new RegExp(`(?:p|pen)\\.${method}\\([^)]*\\)(?!\\.(?:${gocMethods.join('|')}))`, 'g')
              const singleMatches = processedCode.match(singleMethodRegex)
              
              if (singleMatches) {
                singleMatches.forEach(singleMatch => {
                  const normalizedSingle = singleMatch.replace(/^p\./, 'pen.')
                  if (!gocDrawingCommands.includes(normalizedSingle)) {
                    gocDrawingCommands.push(normalizedSingle)
                    logger.log(`➕ 添加单独调用: ${normalizedSingle}`)
                  }
                })
              }
            })
            
            // 🔥 最终验证：确保所有GOC指令都被提取
            logger.log('🎉 最终提取的所有GOC命令:', gocDrawingCommands)
            logger.log('📊 提取统计:')
            logger.log(`  - 总共提取了 ${gocDrawingCommands.length} 个GOC指令`)
            
            // 按指令类型分组统计
            const commandTypes = {}
            gocDrawingCommands.forEach(cmd => {
              const match = cmd.match(/pen\.([a-zA-Z]+)/)
              if (match) {
                const cmdType = match[1]
                commandTypes[cmdType] = (commandTypes[cmdType] || 0) + 1
              }
            })
            logger.log('  - 指令类型统计:', commandTypes)
            
            // 🎯 特别检查链式调用指令
            const chainRelatedCommands = gocDrawingCommands.filter(cmd => 
              cmd.includes('rt') || cmd.includes('fd') || cmd.includes('lt')
            )
            logger.log('  - 链式调用相关指令:', chainRelatedCommands)
            logger.log(`  - 应该有6个链式调用指令 (rt, fd, lt, fd, lt, fd)，实际提取了 ${chainRelatedCommands.length} 个`)
            
            // 🎯 详细分析链式调用指令
            const expectedChainCommands = ['rt', 'fd', 'lt', 'fd', 'lt', 'fd']
            const actualChainCommands = chainRelatedCommands.map(cmd => {
              const match = cmd.match(/pen\.([a-zA-Z]+)/)
              return match ? match[1] : 'unknown'
            })
            logger.log('  - 预期链式指令序列:', expectedChainCommands)
            logger.log('  - 实际链式指令序列:', actualChainCommands)
            
            if (actualChainCommands.length !== expectedChainCommands.length) {
              logger.warn(`  ⚠️ 链式指令数量不匹配！预期${expectedChainCommands.length}个，实际${actualChainCommands.length}个`)
            }
            
            if (gocDrawingCommands.length > 0) {
              // 只保留绘图命令，包装为完整的main函数
              const drawingCode = gocDrawingCommands.join(';\n') + ';'
              processedCode = `int main() {\n${drawingCode}\n}`
              logger.log('🎯 提取的绘图命令:', gocDrawingCommands)
            } else {
              // 如果没有找到绘图命令，检查是否已经包含main函数
              if (!processedCode.includes('int main') && !processedCode.includes('main(')) {
                processedCode = `int main() {\n${processedCode}\n}`
              }
            }
            
            logger.log('🔧 处理后的代码:', processedCode)
            
            // 分词 -> 解析 -> 执行并收集trace
            const tokens = tokenize(processedCode)
            const ast = parse(tokens)
            
            // 执行代码并收集trace
            await execute(ast, virtualCtx, traceCollector)
            
            // 获取生成的trace数据
            const traceData = traceCollector.getTrace()
            
            // 🎯 保存trace到变量并输出到控制台
            this.answerTrace = traceData
            logger.log('🎉 答案代码trace转换完成！')
            logger.log('📊 Trace数据:', this.answerTrace)
            logger.log('📈 Trace统计:', traceCollector.getStats())
            
            // 🔥 验证trace完整性
            logger.log('🔍 验证trace完整性:')
            logger.log(`  - 提取的GOC指令数量: ${gocDrawingCommands.length}`)
            logger.log(`  - 实际执行的trace数量: ${traceData.length}`)
            
            if (traceData.length < gocDrawingCommands.length) {
              logger.warn('⚠️ 检测到trace数据不完整！')
              logger.warn('  - 可能原因: 条件语句阻止了某些指令的执行')
              logger.warn('  - 建议: 检查代码中的条件逻辑')
              
              // 找出缺失的指令
              const executedCommands = traceData.map(t => t.cmd)
              const expectedCommands = gocDrawingCommands.map(cmd => {
                const match = cmd.match(/pen\.([a-zA-Z]+)/)
                return match ? match[1] : 'unknown'
              })
              
              logger.warn('  - 预期指令:', expectedCommands)
              logger.warn('  - 实际执行:', executedCommands)
              
              // 找出缺失的指令
              const missingCommands = []
              expectedCommands.forEach((expected, index) => {
                if (index >= executedCommands.length || executedCommands[index] !== expected) {
                  missingCommands.push(`${expected} (位置${index + 1})`)
                }
              })
              
              if (missingCommands.length > 0) {
                logger.warn('  - 缺失的指令:', missingCommands)
              }
            }
            
            // 输出trace的JSON格式（便于查看）
            logger.log('📋 Trace JSON格式:', traceCollector.exportJSON())
            
          } catch (traceError) {
            logger.error('❌ 答案代码trace转换失败:', traceError)
            logger.error('📋 原始答案代码:', this.answerCode)
            this.answerTrace = null
            
            // 尝试更宽松的处理方式
            try {
              logger.log('🔄 尝试更宽松的代码处理...')
              
              // 重新导入所需的工具函数（在catch块中重新声明）
              const { tokenize: fallbackTokenize } = await import('@/utils/goc-tokenizer')
              const { parse: fallbackParse } = await import('@/utils/goc-parser')
              const { execute: fallbackExecute } = await import('@/utils/goc-interpreter')
              const { default: FallbackTraceCollector } = await import('@/utils/goc-trace-collector')
              
              // 重新创建虚拟环境
              const fallbackTraceCollector = new FallbackTraceCollector()
              const fallbackCanvas = document.createElement('canvas')
              fallbackCanvas.width = 800
              fallbackCanvas.height = 600
              const fallbackCtx = fallbackCanvas.getContext('2d')
              
                // 🔥 使用相同的扩展GOC方法列表（fallback模式）
                const fallbackGocMethods = [
                  // 基本运动控制
                  'fd', 'bk', 'rt', 'lt', 'moveTo', 'lineTo',
                  // 笔状态控制
                  'up', 'down', 'size', 'speed', 'show', 'hide',
                  // 颜色控制
                  'c', 'rgb',
                  // 几何图形绘制
                  'o', 'oo',           // 圆形（空心、实心）
                  'e', 'ee',           // 椭圆（空心、实心）
                  'r', 'rr',           // 矩形（空心、实心）
                  // 图片操作
                  'pic',
                  // 文本操作
                  'text', 'setprecision', 'textSize', 'textU', 'font',
                  // 系统控制
                  'cls',               // 清屏
                  'wait',              // 等待
                  // 辅助功能
                  'showXY'
                ]
              
              const fallbackMethodPattern = `(?:${fallbackGocMethods.join('|')})`
              const fallbackChainPattern = new RegExp(
                `(?:p|pen)\\.${fallbackMethodPattern}\\([^)]*\\)(?:\\.${fallbackMethodPattern}\\([^)]*\\))*`,
                'g'
              )
              
              const fallbackGocCommands = []
              const fallbackChainCommands = this.answerCode.match(fallbackChainPattern)
              logger.log('🔄 Fallback模式 - 链式调用匹配结果:', fallbackChainCommands)
              
              if (fallbackChainCommands && fallbackChainCommands.length > 0) {
                fallbackChainCommands.forEach((chainCmd, index) => {
                  logger.log(`🔄 Fallback - 处理第${index + 1}个链式调用:`, chainCmd)
                  
                // 统一转换为pen.xxx()格式
                  const normalizedChain = chainCmd.replace(/^p\./, 'pen.')
                  logger.log('🔄 Fallback - 标准化链式调用:', normalizedChain)
                  
                  // 🎯 拆分链式调用为单独的方法调用（只保留拆分后的单独调用）
                  const fallbackIndividualCalls = []
                  const singleCallPattern = new RegExp(`\\.?(${fallbackMethodPattern})\\(([^)]*)\\)`, 'g')
                  let match
                  while ((match = singleCallPattern.exec(normalizedChain)) !== null) {
                    const methodName = match[1]
                    const methodArgs = match[2]
                    const individualCall = `pen.${methodName}(${methodArgs})`
                    fallbackIndividualCalls.push(individualCall)
                    logger.log(`  ↳ Fallback - 拆分出单个调用: ${individualCall}`)
                  }
                  
                  logger.log(`🎯 Fallback - 从链式调用中拆分出 ${fallbackIndividualCalls.length} 个单独调用:`, fallbackIndividualCalls)
                  
                  // 🔥 添加所有拆分后的单独调用（允许相同指令多次调用）
                  fallbackIndividualCalls.forEach(call => {
                    fallbackGocCommands.push(call)
                    logger.log(`  ➕ Fallback - 添加指令: ${call}`)
                  })
                })
                
                // 🎯 处理单独的非链式调用（Fallback模式）
                fallbackGocMethods.forEach(method => {
                  const singleMethodRegex = new RegExp(`(?:p|pen)\\.${method}\\([^)]*\\)(?!\\.(?:${fallbackGocMethods.join('|')}))`, 'g')
                  const singleMatches = this.answerCode.match(singleMethodRegex)
                  
                  if (singleMatches) {
                    singleMatches.forEach(singleMatch => {
                      const normalizedSingle = singleMatch.replace(/^p\./, 'pen.')
                      if (!fallbackGocCommands.includes(normalizedSingle)) {
                        fallbackGocCommands.push(normalizedSingle)
                        logger.log(`➕ Fallback - 添加单独调用: ${normalizedSingle}`)
                      }
                    })
                  }
                })
                
                const simpleCode = fallbackGocCommands.join(';\n') + ';'
                const wrappedCode = `int main() {\n${simpleCode}\n}`
                
                logger.log('🎯 Fallback - 提取的GOC命令:', fallbackGocCommands)
                logger.log('🔧 Fallback - 简化包装代码:', wrappedCode)
                
                const tokens = fallbackTokenize(wrappedCode)
                const ast = fallbackParse(tokens)
                await fallbackExecute(ast, fallbackCtx, fallbackTraceCollector)
                
                const traceData = fallbackTraceCollector.getTrace()
                this.answerTrace = traceData
                
                logger.log('🎉 使用简化方式转换成功！')
                logger.log('📊 Trace数据:', this.answerTrace)
                logger.log('📈 Trace统计:', fallbackTraceCollector.getStats())
                logger.log('📋 Trace JSON格式:', fallbackTraceCollector.exportJSON())
                
              } else {
                logger.warn('⚠️ 无法从答案代码中提取有效的GOC命令')
              }
              
            } catch (fallbackError) {
              logger.error('❌ 简化方式也失败了:', fallbackError)
            }
          }
        }
        
      } catch (error) {
        logger.error('❌ 获取答案代码失败:', error)
        this.answerCode = '// 获取答案代码失败：' + (error.message || '未知错误')
        
        // 用户友好的错误提示
        if (error.message && error.message.includes('404')) {
          alert('该题目暂无答案代码')
        } else if (error.message && error.message.includes('403')) {
          alert('您没有权限查看该题目的答案代码')
        } else {
          alert('获取答案代码失败，请稍后重试')
        }
      } finally {
        this.loadingAnswer = false
      }
    },

     // 复制答案代码到剪贴板
     async copyAnswerCode() {
       if (!this.answerCode) {
         alert('暂无答案代码可复制')
         return
       }

       try {
         await navigator.clipboard.writeText(this.answerCode)
         logger.log('✅ 答案代码已复制到剪贴板')
         
         // 显示成功提示
         const button = event.target.closest('.copy-code-btn')
         if (button) {
           const originalText = button.innerHTML
           button.innerHTML = '<i class="fas fa-check"></i> 已复制'
           button.disabled = true
           
           setTimeout(() => {
             button.innerHTML = originalText
             button.disabled = false
           }, 2000)
         }
         
       } catch (error) {
         logger.error('❌ 复制答案代码失败:', error)
         
         // 备用方案：使用旧的复制方法
         try {
           const textArea = document.createElement('textarea')
           textArea.value = this.answerCode
           document.body.appendChild(textArea)
           textArea.select()
           document.execCommand('copy')
           document.body.removeChild(textArea)
           
           // 🔥 显示复制成功提示（1秒后自动关闭）
           if (this.$message && this.$message.success) {
             this.$message.success({
               message: '已复制',
               duration: 1000
             })
           } else {
             this.showAutoCloseMessage('已复制')
           }
           logger.log('✅ 使用备用方法复制成功')
         } catch (fallbackError) {
           logger.error('❌ 备用复制方法也失败:', fallbackError)
           alert('复制失败，请手动选择并复制代码')
         }
       }
     },
     
     
     // 复制正确答案到剪贴板
     async copyCorrectAnswer() {
       if (!this.problem || !this.problem.answer) {
         alert('暂无正确答案可复制')
         return
       }

       try {
         await navigator.clipboard.writeText(this.problem.answer)
         logger.log('✅ 正确答案已复制到剪贴板')
         
         // 显示成功提示
         const button = event.target.closest('.copy-answer-btn')
         if (button) {
           const originalText = button.innerHTML
           button.innerHTML = '<i class="fas fa-check"></i> 已复制'
           button.disabled = true
           
           setTimeout(() => {
             button.innerHTML = originalText
             button.disabled = false
           }, 2000)
         }
         
       } catch (error) {
         logger.error('❌ 复制正确答案失败:', error)
         
         // 备用方案：使用旧的复制方法
         try {
           const textArea = document.createElement('textarea')
           textArea.value = this.problem.answer
           document.body.appendChild(textArea)
           textArea.select()
           document.execCommand('copy')
           document.body.removeChild(textArea)
           
           // 🔥 显示复制成功提示（1秒后自动关闭）
           if (this.$message && this.$message.success) {
             this.$message.success({
               message: '已复制',
               duration: 1000
             })
           } else {
             this.showAutoCloseMessage('已复制')
           }
           logger.log('✅ 使用备用方法复制成功')
         } catch (fallbackError) {
           logger.error('❌ 备用复制方法也失败:', fallbackError)
           alert('复制失败，请手动选择并复制代码')
         }
       }
     },

     // 格式化日期时间
    formatDateTime(dateTimeStr) {
      if (!dateTimeStr) return ''
      try {
        const date = new Date(dateTimeStr)
        return date.toLocaleString('zh-CN', {
          year: 'numeric',
          month: '2-digit',
          day: '2-digit',
          hour: '2-digit',
          minute: '2-digit',
          second: '2-digit'
        })
      } catch (error) {
        return dateTimeStr
      }
    },
    

    // 编辑题目
    editQuestion() {
      if (this.problem && this.problem.id) {
        logger.log('✏️ [ProblemDetail] 跳转到编辑页面，题目ID:', this.problem.id);
        this.$router.push(`/question/edit/${this.problem.id}`);
      }
    },

    // 获取当前用户ID
    getCurrentUserId() {
      try {
        // 从JWT令牌解析用户ID
        const token = localStorage.getItem('token');
        if (token) {
          const tokenParts = token.split('.');
          if (tokenParts.length === 3) {
            const payload = JSON.parse(atob(tokenParts[1]));
            const jwtUserId = payload.claims?.id;
            if (jwtUserId) {
              return String(jwtUserId);
            }
          }
        }
        
        // 备选方案：从localStorage获取
        const userInfoStr = localStorage.getItem('userInfo');
        if (userInfoStr) {
          const userInfo = JSON.parse(userInfoStr);
          return String(userInfo.id || '1953810929896525824');
        }
      } catch (error) {
        logger.error('❌ [ProblemDetail] 获取用户ID失败:', error);
      }
      return '1953810929896525824';
    },

    // 格式化空间限制显示
    formatSpaceLimit(spaceLimitBytes) {
      if (!spaceLimitBytes) return '';
      
      const bytes = Number(spaceLimitBytes);
      if (bytes >= 1048576) { // >= 1MB
        return `${(bytes / 1048576).toFixed(1)}MB`;
      } else if (bytes >= 1024) { // >= 1KB
        return `${(bytes / 1024).toFixed(1)}KB`;
      } else {
        return `${bytes}字节`;
      }
    },

    // 开始解题 - 显示Goc判题组件
    startSolving() {
      logger.log('🚀 开始解题，显示Goc判题组件')
      this.showGocJudge = true
      
      // 滚动到判题组件位置
      this.$nextTick(() => {
        const judgeSection = document.querySelector('.goc-judge-section')
        if (judgeSection) {
          judgeSection.scrollIntoView({ behavior: 'smooth' })
        }
      })
    },

    // 隐藏Goc判题组件
    hideGocJudge() {
      logger.log('❌ 关闭Goc判题组件')
      this.showGocJudge = false
    },

    // 判题完成回调
    onJudgeComplete(result) {
      logger.log('✅ 判题完成:', result)
      
      // 显示判题结果
      const statusText = result.status === 'AC' ? '通过' : '未通过'
      const message = `判题结果：${statusText}\n得分：${result.score}/${result.totalScore}\n通过测试用例：${result.passedCases}/${result.totalCases}\n执行时间：${result.executionTime}ms`
      
      if (result.status === 'AC') {
        this.$message?.success(`🎉 恭喜通过！得分：${result.score}/${result.totalScore}`)
      } else {
        this.$message?.warning(`判题结果：${statusText}，得分：${result.score}/${result.totalScore}`)
      }
    },

    // 代码提交回调
    onCodeSubmit(data) {
      logger.log('📝 代码提交数据:', data)
      // 这里可以将代码提交到后端保存
    },

    // 判题错误回调
    onJudgeError(error) {
      logger.error('❌ 判题错误:', error)
      this.$message?.error('判题过程中发生错误，请重试！')
    },

    // 图片加载成功回调
    onImageLoad(event) {
      logger.log('✅ 题目图片加载成功:', event.target.src)
    },

    // 图片加载失败回调
    onImageError(event) {
      logger.error('❌ 题目图片加载失败:', event.target.src)
      
      // 显示错误提示
      const img = event.target
      img.style.display = 'none'
      
      // 在图片容器中显示错误信息
      const container = img.parentElement
      if (container && !container.querySelector('.image-error')) {
        const errorDiv = document.createElement('div')
        errorDiv.className = 'image-error'
        errorDiv.innerHTML = '📷 图片加载失败，可能是链接无效或网络问题'
        container.appendChild(errorDiv)
      }
    },
    
    // 🔥 显示自动关闭的消息提示（1秒后自动关闭）
    showAutoCloseMessage(message) {
      const messageEl = document.createElement('div')
      messageEl.className = 'auto-close-message'
      messageEl.textContent = message
      messageEl.style.cssText = `
        position: fixed;
        top: 20px;
        left: 50%;
        transform: translateX(-50%);
        background: #67C23A;
        color: white;
        padding: 12px 24px;
        border-radius: 6px;
        box-shadow: 0 4px 12px rgba(103, 194, 58, 0.4);
        z-index: 10000;
        font-size: 14px;
        font-weight: 500;
        animation: slideDown 0.3s ease-out;
      `
      
      document.body.appendChild(messageEl)
      
      // 1秒后自动移除
      setTimeout(() => {
        messageEl.style.animation = 'slideUp 0.3s ease-out'
        setTimeout(() => {
          document.body.removeChild(messageEl)
        }, 300)
      }, 1000)
    }
  },
  
  // 路由参数变化时重新加载
  watch: {
    '$route.params.id': {
      handler() {
        this.loadProblemDetail()
      },
      immediate: false
    }
  },
  
  beforeUnmount() {
    logger.log('🧹 [ProblemDetail] 页面即将卸载，清理资源')
    
    try {
      // 如果编辑器正在显示，先隐藏它
      if (this.showGocJudge) {
        this.hideGocJudge()
      }
      
      // 清理全局变量
      delete window.__gocUpdatePen
      delete window.__gocSetPenVisible
      
      logger.log('✅ [ProblemDetail] 页面清理完成')
    } catch (error) {
      logger.warn('⚠️ [ProblemDetail] 清理时出错:', error)
    }
  }
}
</script>

<style scoped>
/* 自动关闭消息提示动画 */
@keyframes slideDown {
  from {
    opacity: 0;
    transform: translateX(-50%) translateY(-20px);
  }
  to {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
  }
}

@keyframes slideUp {
  from {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
  }
  to {
    opacity: 0;
    transform: translateX(-50%) translateY(-20px);
  }
}

.problem-detail-page {
  padding: 10px 0;
  min-height: 100vh;
  background-color: #f7f9fc;
}

.container {
  max-width: 100%;
  margin: 0 auto;
  padding: 0 15px;
}

.navigation {
  margin-bottom: 20px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.back-btn {
  background: linear-gradient(135deg, #3498db, #2980b9);
  color: white;
  border: none;
  padding: 10px 20px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 14px;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 8px;
  transition: all 0.3s ease;
  box-shadow: 0 2px 8px rgba(52, 152, 219, 0.2);
}

.back-btn:hover {
  background: linear-gradient(135deg, #2980b9, #21618c);
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(52, 152, 219, 0.3);
}

.back-btn:active {
  transform: translateY(0);
}

.back-btn i {
  font-size: 14px;
}

.action-buttons {
  display: flex;
  gap: 10px;
}

.edit-btn {
  background: linear-gradient(135deg, #667eea, #764ba2);
  color: white;
  border: none;
  padding: 10px 20px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 14px;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 6px;
  transition: all 0.3s ease;
}

.edit-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
}

.edit-btn i {
  font-size: 12px;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .navigation {
    flex-direction: column;
    gap: 15px;
    align-items: stretch;
  }

  .back-btn {
    justify-content: center;
    width: 100%;
  }

  .action-buttons {
    justify-content: center;
  }

  .edit-btn {
    justify-content: center;
  }
}

.data-source-notice {
  background: linear-gradient(135deg, #e8f5e8, #d4edda);
  border: 1px solid #c3e6cb;
  border-radius: 8px;
  padding: 12px 16px;
  margin-top: 20px;
  color: #155724;
  font-size: 14px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.data-source-notice i {
  color: #28a745;
  font-size: 16px;
}

.loading-container,
.error-container,
.no-data-container {
  text-align: center;
  padding: 60px 20px;
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
}

.loading-spinner {
  font-size: 48px;
  margin-bottom: 20px;
}

.error-icon,
.no-data-icon {
  font-size: 48px;
  margin-bottom: 20px;
}

.retry-btn {
  background-color: #3e8ef7;
  color: white;
  border: none;
  padding: 10px 20px;
  border-radius: 4px;
  cursor: pointer;
  margin-top: 10px;
}

.problem-content {
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
  overflow: hidden;
}

.problem-header {
  padding: 30px;
  border-bottom: 1px solid #eee;
}

.problem-title {
  font-size: 28px;
  font-weight: 600;
  margin-bottom: 15px;
  color: #333;
}

.problem-meta {
  display: flex;
  gap: 15px;
  align-items: center;
  flex-wrap: wrap;
}

.problem-id {
  color: #666;
  font-size: 14px;
}

.type-tag {
  display: inline-block;
  padding: 4px 12px;
  border-radius: 4px;
  font-size: 12px;
  background-color: #1890ff;
  color: white;
}

.difficulty-tag {
  display: inline-block;
  padding: 4px 12px;
  border-radius: 4px;
  font-size: 12px;
  color: white;
}

.difficulty-tag.level-1,
.difficulty-tag.level-2 {
  background-color: #52c41a;
}

.difficulty-tag.level-3,
.difficulty-tag.level-4 {
  background-color: #fa8c16;
}

.difficulty-tag.level-5,
.difficulty-tag.level-6 {
  background-color: #f5222d;
}

.complete-rate,
.time-limit,
.space-limit,
.problem-label {
  color: #666;
  font-size: 14px;
}

.public-tag {
  display: inline-block;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 500;
}

.public-tag.public {
  background-color: #f6ffed;
  color: #52c41a;
  border: 1px solid #b7eb8f;
}

.public-tag.private {
  background-color: #fff2e8;
  color: #fa8c16;
  border: 1px solid #ffd591;
}

.problem-section {
  padding: 25px 30px;
  border-bottom: 1px solid #eee;
}

.problem-section:last-child {
  border-bottom: none;
}

.problem-section h3 {
  font-size: 18px;
  font-weight: 600;
  margin-bottom: 15px;
  color: #333;
}

.problem-description,
.problem-explanation,
.problem-input-format,
.problem-output-format,
.problem-range-prompt {
  line-height: 1.6;
  color: #555;
  font-size: 15px;
}

/* 🔥 题目描述图片 */
.problem-describe-image {
  margin-top: 15px;
  text-align: center;
  padding: 15px;
  background: #f8f9fa;
  border-radius: 8px;
}

.describe-image {
  max-width: 600px;
  max-height: 500px;
  height: auto;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  border: 1px solid #e1e4e8;
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.describe-image:hover {
  transform: scale(1.02);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2);
  cursor: zoom-in;
}

.problem-input-format,
.problem-output-format {
  background-color: #f8f9fa;
  padding: 15px;
  border-radius: 6px;
  border-left: 4px solid #3e8ef7;
}

.problem-range-prompt {
  background-color: #fff7e6;
  padding: 15px;
  border-radius: 6px;
  border-left: 4px solid #fa8c16;
}

.problem-options {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.option-item {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 10px;
  background-color: #f8f9fa;
  border-radius: 4px;
}

.option-label {
  font-weight: 600;
  color: #3e8ef7;
  min-width: 20px;
}

.option-text {
  flex: 1;
  line-height: 1.5;
}

.answer-section {
  background-color: #fff7e6;
}

.answer-container {
  position: relative;
}

.problem-answer {
  font-weight: 600;
  color: #d4b106;
  font-size: 16px;
  white-space: pre !important;
  font-family: 'Courier New', Consolas, 'Liberation Mono', monospace;
  background-color: #2d3748;
  color: #e2e8f0;
  padding: 15px;
  border-radius: 6px;
  overflow-x: auto;
  line-height: 1.6;
  margin-bottom: 15px;
}

.answer-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

.copy-answer-btn {
  padding: 8px 16px;
  background-color: #ffa726;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
  transition: all 0.3s ease;
  display: flex;
  align-items: center;
  gap: 5px;
}

.copy-answer-btn:hover:not(:disabled) {
  background-color: #fb8c00;
  transform: translateY(-1px);
}

.copy-answer-btn:disabled {
  background-color: #6c757d;
  cursor: not-allowed;
  transform: none;
}

.copy-answer-btn i {
  font-size: 12px;
}


.code-template {
  background-color: #f6f8fa;
  border: 1px solid #e1e4e8;
  border-radius: 6px;
  padding: 16px;
  overflow-x: auto;
  font-family: 'Courier New', monospace;
  font-size: 14px;
  line-height: 1.4;
}



.problem-tags {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.tag-item {
  display: inline-block;
  padding: 4px 8px;
  background-color: #e6f3ff;
  color: #1890ff;
  border-radius: 4px;
  font-size: 12px;
}

.info-section {
  background-color: #fafafa;
}

.problem-info {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.info-item {
  font-size: 14px;
  color: #666;
}

.info-item strong {
  color: #333;
}

.problem-actions {
  padding: 25px 30px;
  background-color: #f8f9fa;
  display: flex;
  gap: 15px;
}

.action-btn {
  padding: 10px 20px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  font-weight: 500;
}

.show-answer-btn,
.hide-answer-btn {
  background-color: #17a2b8;
  color: white;
  position: relative;
}

.show-answer-btn:hover,
.hide-answer-btn:hover {
  background-color: #138496;
}

/* 学生账号禁用状态 */
.show-answer-btn.disabled,
.show-answer-btn:disabled {
  background-color: #6c757d;
  cursor: not-allowed;
  opacity: 0.6;
}

.show-answer-btn.disabled:hover,
.show-answer-btn:disabled:hover {
  background-color: #6c757d;
}

.student-lock {
  margin-left: 5px;
  font-size: 12px;
}

.start-solve-btn {
  background-color: #28a745;
  color: white;
}

.start-solve-btn:hover {
  background-color: #218838;
}

@media (max-width: 768px) {
  .container {
    padding: 0 15px;
  }
  
  .problem-header,
  .problem-section,
  .problem-actions {
    padding: 20px;
  }
  
  .problem-meta {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }
  
  .problem-actions {
    flex-direction: column;
  }
}

/* Goc判题组件样式 */
.goc-judge-section {
  margin-top: 30px;
  border: 2px solid #007bff;
  border-radius: 12px;
  background: #fff;
  box-shadow: 0 8px 32px rgba(0, 123, 255, 0.1);
  overflow: hidden;
  min-height: 80vh;
  width: 100%;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 15px 20px;
  background: linear-gradient(45deg, #007bff, #0056b3);
  color: white;
  margin-bottom: 0;
}

.section-header h3 {
  margin: 0;
  font-size: 1.2rem;
  font-weight: 600;
}

.close-judge-btn {
  background: rgba(255, 255, 255, 0.2);
  color: white;
  border: 1px solid rgba(255, 255, 255, 0.3);
  padding: 6px 12px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 0.9rem;
  transition: all 0.3s ease;
}

.close-judge-btn:hover {
  background: rgba(255, 255, 255, 0.3);
  border-color: rgba(255, 255, 255, 0.5);
}

/* 答案代码样式 */
.answer-code-section {
  background-color: #f8f9fa;
  border-left: 4px solid #28a745;
}

.answer-code-section h3 {
  color: #28a745;
  display: flex;
  align-items: center;
  gap: 10px;
}

.loading-indicator {
  font-size: 14px;
  color: #6c757d;
  font-weight: normal;
}

.loading-indicator i {
  margin-right: 5px;
}

.answer-code-container {
  position: relative;
}

.answer-code {
  background-color: #2d3748;
  color: #e2e8f0;
  padding: 20px;
  border-radius: 8px;
  font-family: 'Courier New', Consolas, 'Liberation Mono', monospace !important;
  font-size: 14px;
  line-height: 1.6;
  overflow-x: auto;
  white-space: pre !important;
  margin-bottom: 15px;
  border: 1px solid #4a5568;
  display: block;
}

.answer-code code {
  background: none !important;
  color: inherit;
  padding: 0;
  font-size: inherit;
  font-family: inherit !important;
  white-space: inherit !important;
  display: inline;
}

.code-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

.copy-code-btn {
  padding: 8px 16px;
  background-color: #28a745;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
  transition: all 0.3s ease;
  display: flex;
  align-items: center;
  gap: 5px;
}

.copy-code-btn:hover:not(:disabled) {
  background-color: #218838;
  transform: translateY(-1px);
}

.copy-code-btn:disabled {
  background-color: #6c757d;
  cursor: not-allowed;
  transform: none;
}

.copy-code-btn i {
  font-size: 12px;
}

/* 题目图片样式 */
.problem-image-container {
  margin-top: 20px;
  text-align: center;
}

.problem-image {
  max-width: 100%;
  height: auto;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  border: 1px solid #e1e4e8;
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.problem-image-small {
  max-width: 400px;
  height: auto;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  border: 1px solid #e1e4e8;
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.problem-image:hover {
  transform: scale(1.02);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2);
  cursor: zoom-in;
}

.problem-image-small:hover {
  transform: scale(1.02);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2);
  cursor: zoom-in;
}

.image-caption {
  margin-top: 10px;
  font-size: 14px;
  color: #666;
  font-style: italic;
}

/* 输出格式图片样式 */
.output-image-container {
  margin-top: 15px;
  text-align: center;
  padding: 15px;
  background: #f8f9fa;
  border-radius: 8px;
}

.output-format-image {
  max-width: 400px;
  height: auto;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  border: 1px solid #e1e4e8;
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.output-format-image:hover {
  transform: scale(1.02);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2);
  cursor: zoom-in;
}

.image-error {
  padding: 20px;
  background-color: #fff2f0;
  border: 1px solid #ffccc7;
  border-radius: 6px;
  color: #cf1322;
  font-size: 14px;
  margin-top: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .answer-code {
    font-size: 13px;
    padding: 15px;
  }
  
  .code-actions, .answer-actions {
    justify-content: center;
  }
  
  .copy-code-btn, .copy-answer-btn {
    width: 100%;
    justify-content: center;
  }

  .problem-image, .problem-image-small {
    border-radius: 6px;
  }
  
  .problem-image:hover, .problem-image-small:hover {
    transform: none;
  }
}

/* 测试用例显示样式 */
.problem-test-cases {
  background: #f8f9fa;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  padding: 16px;
  font-family: 'Courier New', Consolas, monospace;
  font-size: 14px;
  line-height: 1.6;
  color: #333;
  overflow-x: auto;
  white-space: pre-wrap;
}

/* 简洁的测试用例容器样式 */
.test-cases-container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 16px;
  margin-top: 16px;
}

.test-case-item {
  background: #ffffff;
  border: 2px solid #e8f4fd;
  border-radius: 12px;
  padding: 16px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
  transition: all 0.3s ease;
  text-align: center;
}

.test-case-item:hover {
  border-color: #2196F3;
  box-shadow: 0 6px 20px rgba(33, 150, 243, 0.2);
  transform: translateY(-4px);
}

.test-case-header-mini {
  background: linear-gradient(135deg, #667eea, #764ba2);
  color: white;
  padding: 10px 15px;
  border-radius: 8px 8px 0 0;
  margin: -16px -16px 12px -16px;
  text-align: center;
  font-weight: 600;
}

.case-number {
  font-size: 14px;
}

.test-case-data {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.test-case-section {
  display: flex;
  flex-direction: column;
  gap: 8px;
  text-align: left;
}

.test-case-section label {
  font-size: 13px;
  font-weight: 600;
  color: #666;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.input-data {
  font-family: 'Courier New', Consolas, monospace;
  font-size: 14px;
  color: #2196F3;
  background: linear-gradient(135deg, #e3f2fd, #f8f9fa);
  padding: 12px 16px;
  border-radius: 8px;
  border: 2px solid #e3f2fd;
  white-space: pre-wrap;
  word-break: break-word;
  min-height: 40px;
  line-height: 1.6;
}

.output-data {
  font-family: 'Courier New', Consolas, monospace;
  font-size: 14px;
  color: #FF9800;
  background: linear-gradient(135deg, #fff3e0, #f8f9fa);
  padding: 12px 16px;
  border-radius: 8px;
  border: 2px solid #fff3e0;
  white-space: pre-wrap;
  word-break: break-word;
  min-height: 40px;
  line-height: 1.6;
}

.output-image-data {
  padding: 12px;
  background: #f8f9fa;
  border-radius: 8px;
  border: 2px solid #e0e0e0;
  text-align: center;
}

.test-case-image {
  max-width: 100%;
  max-height: 300px;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  transition: transform 0.3s ease;
}

.test-case-image:hover {
  transform: scale(1.02);
  cursor: zoom-in;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .test-cases-container {
    grid-template-columns: 1fr;
    gap: 12px;
  }
  
  .test-case-item {
    padding: 12px;
  }
  
  .input-data,
  .output-data {
    font-size: 16px;
    padding: 10px 12px;
  }
}
</style> 